import cv2
import matplotlib.pyplot as plt
import numpy as np 

import sys ,time ,json
import pymodules.imgproc as imgproc
import pymodules.camera as camera
import pymodules.robot as robot
import pymodules.modbus as bus 


from PyQt5.QtCore import*
from PyQt5.QtGui import *
from PyQt5.QtWidgets import*

import test_methods,test_ui
from paho.mqtt.client import Client
from scipy.spatial import distance

from PIL import Image
from pyzbar import pyzbar


PCBPOS={'x':186,'y':82,'z':50} #132
OKPOS={'x':16,'y':-165,'z':25} #123
NGPOS={'x':42,'y':166,'z':20}  # 66



class main(test_ui.MyWidget):
    def __init__(self):
        super().__init__()

        self.create()

    def create(self):
        print('create')
        self.t=QTimer()
        self.ok=0
        self.ng=0
        self.isok=1


        self.host ='192.168.1.1'
        self.port =9006
        self.username = 'gdip'
        self.userpwd='gdip'
        self.client=Client('gdip')

        self.t.timeout.connect(self.tout)
        self.btnCapture.clicked.connect(self.capture)
        self.btnExit.clicked.connect(self.exit)
        self.btnStop.clicked.connect(self.stop)
        self.btnStart.clicked.connect(self.start)


    def tout(self):
        print('tout')
        self.t.stop()
        needrobot = bus.readIoChannel(2)
        needcamera = bus.readIoChannel(0)

        if needcamera:
            bus.writeIoChannel(5,True)
            time.sleep(5)
            bus.writeIoChannel(7,False)

            img = camera.getImageAsFile(3000,'./img')
            
            img1 =cv2.imread(img)
            if img1 is None:
                print('1 is None')
            x,y,w,h=484,614,2972,2168
            img1=img1[y:y+h,x:x+w]

            cv2.imwrite('./img/one.png',img1)
            self.setimg(self.labelPicOne,'./img/one.png')
            bus.writeIoChannel(5,False)
            bus.writeIoChannel(7,True)

            img2 =cv2.imread('/ssd/Test01/1.bmp',0)
         
            for i in range(img2.shape[0]):
                for j in range(img2.shape[1]):
                    if img2[i][j]>70:
                        img2[i][j]=255
                    else:
                        img2[i][j]=0

            cv2.imwrite('./img/two.png',img2)
            self.setimg(self.labelPicTwo,'./img/two.png')
            img3 =cv2.imread('./img/two.png')
            gray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
            thresh = cv2.threshold(gray,120,255,cv2.THRESH_BINARY)[1]
            contour = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
            mx=0
            for i in contour:
                if cv2.contourArea(i)>mx:
                    mx=cv2.contourArea(i)

            for i in contour:
                if cv2.contourArea(i)!=mx:
                    x,y,w,h=cv2.boundingRect(i)
                    img3[y:y+h,x:x+w]=0

            cv2.imwrite('./img/three.png',img3)
            self.setimg(self.labelPicThree,'./img/three.png')


            self.proc()
            #画出错误坐标匡
            img4 =cv2.imread('./img/one.png')
            res =np.loadtxt('./result.txt',int,delimiter=',')
            for i in res:
                if i[4]==1:
                    self.ok+=1
                    cv2.rectangle(img4,(i[0],i[1]),(i[0]+i[2],i[1]+i[3]),(0,255,0),8)
                else:
                    self.ng+=1
                    cv2.rectangle(img4,(i[0],i[1]),(i[0]+i[2],i[1]+i[3]),(0,0,255),8)

            cv2.imwrite('./img/four.png',img4)
            self.setimg(self.labelPicFour,'./img/four.png')

            plt.close()
            plt.bar(0,self.ok,0.2,label='ok',color='g')
            plt.bar(0.2,self.ng,0.2,label='ng',color='r')
            plt.legend()
            plt.savefig('./img/info.png')
            self.setimg(self.labelImg,'./img/info.png')
            self.labelInfo.setText("OK :%d,NG:%d"%(self.ok,self.ng))

            # self.mqtt_push()

            if self.ng==0:
                self.isok=1
            else:
                self.isok=2


        if needrobot:
            t1=time.perf_counter()
            bmp =QPixmap(self.size())
            self.render(bmp)  
            saveimg = './img/0_%d.bmp'%t1
            bmp.save(saveimg)
            bus.writeIoChannel(7,False)
            self.getpcb()
            self.ok=0
            self.ng=0

        bus.writeIoChannel(6,True)
        time.sleep(0.1)
        bus.writeIoChannel(6,False)
        bus.writeIoChannel(7,True)
        self.t.start(500)




    def mqtt_connect(self):
        self.client.username_pw_set(self.username,self.userpwd)
        self.client.connect(self.host,self.port,60)

    def mqtt_push(self):
        self.mqtt_connect()
        self.client.loop_start()

        PAY={'type':'xxx','version':'1.0','time':time.time(),'params':{'ok':self.ok,'ng':self.ng}}
        data = json.dumps(PAY)
        self.client.publish('./xxx/xxx',data)
        self.client.loop_stop()


    def proc(self):
        open('./result.txt','w').close()
        needtrain = True
        imgfile='./img/one.png'
        pcbfile='./img/pcb.bmp'
        result = './result.txt'
        ret = imgproc.match_pcb(imgfile,'./ps/gs/1.bmp',0.7,1142,1928,860,240,pcbfile)
        if ret ==False:
            print('match is None')

        imgdst = './img/Canny.bmp'
        imgDst = './img/unevenLightCompensate.bmp'
        imgdst1 = './img/Canny1.bmp'
        imgproc.unevenLightCompensate(imgfile,20,imgDst) 
        imgproc.edge_canny(imgfile,40,80,imgdst)
        imgproc.edge_canny(imgfile,15,60,imgdst1)


        imgok = './ps/part1/ok/'
        imgng='./ps/part1/ng/'
        roitxt = './ps/roi/1.txt'
        xmltxt ='./xml/1.xml'
        t1 = time.perf_counter()
        savebmp = './save/1_%2f.bmp'%t1

        imgproc.train_knn_histgram(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgDst,roitxt,xmltxt,'knn','histgram',savebmp,result)


        imgok = './ps/part2/ok/'
        imgng='./ps/part2/ng/'
        roitxt = './ps/roi/2.txt'
        xmltxt ='./xml/2.xml'
        t2 = time.perf_counter()
        savebmp = './save/2_%2f.bmp'%t2

        imgproc.train_svm_hog(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgdst,roitxt,xmltxt,'svm','hog',savebmp,result)

        imgok = './ps/part3/ok/'
        imgng='./ps/part3/ng/'
        roitxt = './ps/roi/3.txt'
        xmltxt ='./xml/3.xml'
        t3 = time.perf_counter()
        savebmp = './save/3_%2f.bmp'%t3

        imgproc.train_knn_histgram(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgdst,roitxt,xmltxt,'knn','histgram',savebmp,result)


        imgok = './ps/part4/ok/'
        imgng='./ps/part4/ng/'
        roitxt = './ps/roi/4.txt'
        xmltxt ='./xml/4.xml'
        t4 = time.perf_counter()
        savebmp = './save/4_%2f.bmp'%t4

        imgproc.train_svm_hog(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgdst,roitxt,xmltxt,'svm','hog',savebmp,result)



        imgok = './ps/part5/ok/'
        imgng='./ps/part5/ng/'
        roitxt = './ps/roi/5.txt'
        xmltxt ='./xml/5.xml'
        t5 = time.perf_counter()
        savebmp = './save/5_%2f.bmp'%t5

        imgproc.train_svm_hog(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgdst1,roitxt,xmltxt,'svm','hog',savebmp,result)


        imgok = './ps/part6/ok/'
        imgng='./ps/part6/ng/'
        roitxt = './ps/roi/6.txt'
        xmltxt ='./xml/6.xml'
        t6 = time.perf_counter()
        savebmp = './save/5_%2f.bmp'%t6

        imgproc.train_knn_histgram(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgDst,roitxt,xmltxt,'knn','histgram',savebmp,result)
            
        imgok = './ps/part7/ok/'
        imgng='./ps/part7/ng/'
        roitxt = './ps/roi/7.txt'
        xmltxt ='./xml/7.xml'
        t7 = time.perf_counter()
        savebmp = './save/7_%2f.bmp'%t7

        imgproc.train_svm_hog(imgok,imgng,xmltxt)
        if needtrain:
            imgproc.predict(imgDst,roitxt,xmltxt,'svm','hog',savebmp,result)


    
        
        

        







    def getpcb(self):
        v = robot.getCurentPosition()
        if v is None:
            print('v is None')
        

        robot.moveJByXYZ(v['x'],v['y'],70,60)
        robot.waitForPos(v['x'],v['y'],70)

        if v['axis2']<0:
            robot.setRAngel(170)
            robot.moveJByXYZ(PCBPOS['x'],PCBPOS['y'],70,60)
            robot.moveJByXYZ(PCBPOS['x'],PCBPOS['y'],PCBPOS['z'],60)
            robot.waitForPos(PCBPOS['x'],PCBPOS['y'],PCBPOS['z'])
            robot.setV12IoValue(True)
        else:
            robot.setRAngel(132)
            robot.moveJByXYZ(PCBPOS['x'],PCBPOS['y'],70,60)
            robot.moveJByXYZ(PCBPOS['x'],PCBPOS['y'],PCBPOS['z'],60)
            robot.waitForPos(PCBPOS['x'],PCBPOS['y'],PCBPOS['z'])
            robot.setV12IoValue(True)


        robot.moveJByXYZ(PCBPOS['x'],PCBPOS['y'],70,60)
        robot.waitForPos(PCBPOS['x'],PCBPOS['y'],70)

        if self.isok==1:
            robot.moveJByXYZ(OKPOS['x'],OKPOS['y'],70,60)
            robot.waitForPos(OKPOS['x'],OKPOS['y'],70)
            robot.setRAngel(132)
            robot.moveJByXYZ(OKPOS['x'],OKPOS['y'],OKPOS['z'],60)
            robot.waitForPos(OKPOS['x'],OKPOS['y'],OKPOS['z'])
            robot.setV12IoValue(False)
        else:
            robot.moveJByXYZ(NGPOS['x'],NGPOS['y'],70,60)
            robot.waitForPos(NGPOS['x'],NGPOS['y'],70)
            robot.setRAngel(66)
            robot.moveJByXYZ(NGPOS['x'],NGPOS['y'],NGPOS['z'],60)
            robot.waitForPos(NGPOS['x'],NGPOS['y'],NGPOS['z'])
            robot.setV12IoValue(False)


        

    def __del__(self):
        bus.writeIo(0)
        bus.freeModbus()
        camera.freeCamera()
        robot.freeRobot()
        


            

    

    def openall(self):
        print('open')
        bus.initModbus()
        camera.initCamera()
        robot.initRobot()

        bus.openModBus(self.cmbModbus.currentText(),57600)
        robot.openRobotControl(self.cmbRobot.currentText(),115200)
        camera.openCamera()

    def start(self):
        self.openall()

        bus.writeIoChannel(6,True)
        time.sleep(0.1)
        bus.writeIoChannel(6,False)
        bus.writeIoChannel(7,True)
        self.t.start(500)

    def capture(self):
        img =camera.getImageAsFile(3000,'./img')
        if img is None:
            print('img is none')
        
        img = cv2.imread(img)
        cv2.imwrite('./img/one.png',img)

        
    def setimg(self,label:QLabel,imgfile:str):
        map =QPixmap()
        if map.load(imgfile):
            label.setPixmap(map.scaledToHeight(label.height()-2))
        label.repaint()

    def stop(self):
        self.t.stop()
        bus.writeIo(0)

    def exit(self):
        self.stop()
        exit(111)




class dialog(QDialog):
    def __init__(self):
        super().__init__()
        self.resize(1024,1024)
        qp=QPalette()
        qp.setBrush(QPalette.Background,QBrush(QPixmap('/ssd/Test01/1.bmp')))
        self.setPalette(qp)

        frame =QFrame(self)
        qv = QVBoxLayout()
        frame.setLayout(qv)

        self.username = QLineEdit()
        self.userpwd =QLineEdit()
        self.btnlogin=QPushButton('登陆')
        self.btncencle=QPushButton('取消')

        qv.addWidget(self.username)
        qv.addWidget(self.userpwd)
        qv.addWidget(self.btnlogin)
        qv.addWidget(self.btncencle)

        self.setContentsMargins(400,400,400,400)

        self.btnlogin.clicked.connect(self.login)
        self.btncencle.clicked.connect(self.cencle)

    def login(self):
        if self.username.text()=='11'and self.userpwd.text()=='11':
            self.accept()
        else:
            exit(12)

    def cencle(self):
        exit(13)





def show():
    app =QApplication(sys.argv)
    m =main()
    m.show()
    sys.exit(app.exec_())








if __name__=='__main__':
    app =QApplication(sys.argv)
    d =dialog()
    if d.exec_() == QDialog.Accepted:
        show()
    else:
        sys.exit(app.exec_())